
package com.idealighter.game.games.horserace.struct;

import com.google.common.collect.EvictingQueue;
import com.google.common.collect.Maps;

import com.idealighter.game.dictionary.domain.HorseLogPlanDomain;
import com.idealighter.game.games.common.AbstractTable;
import com.idealighter.utils.code.RandCodeUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ScheduledFuture;

/**
 * .. 赛马桌子桌子 .
 * 
 * @date 2016年2月17日 上午10:46:55
 */
public class HorseRaceTable extends AbstractTable {

  // 座位数量
  private static final int SEAT_NUM = 100;
  private static final int HORSE_NUM = 6;
  public static final int HISTORY_SIZE = 30;
  public static final int V = 1000;
  public final HorseRaceRoom room;
  // 房间里面的桌子
  public final List<HorseRaceSeat> seats;
  // 桌上的总筹码
  public long totalChips = 0;
  // 玩家总下注信息
  public Map<Integer, Long> betsTotal = Maps.newConcurrentMap();
  // 当前状态
  public GameStatus status = GameStatus.REST;

  public final EvictingQueue<Integer> history = EvictingQueue.create(HISTORY_SIZE);

  public final Map<Integer, AreBet> areBetMap = Maps.newConcurrentMap();

  public final List<Horse> horses;

  // 游戏步骤(休息、下注、开奖、结算)定时Future
  public ScheduledFuture<?> stepFuture = null;

  public int secenId = 1;

  public long tempGold = 0;
  // 系统收益
  public long earn = 0;
  // 开奖区域
  public int horse;
  // 段数
  // public int segment;
  // 开奖方案
  public List<HorseLogPlanDomain> plan;

  /**
   * 构造函数 .
   * 
   * @param id .
   * @param room .
   */
  public HorseRaceTable(int id, HorseRaceRoom room) {
    super(id);
    this.room = room;
    this.seats = createSeats();
    this.horses = carateHorse();
    createAreMap();

  }

  private List<Horse> carateHorse() {
    List<Horse> horse = new ArrayList<>(HORSE_NUM);
    for (int i = 1; i <= HORSE_NUM; i++) {
      horse.add(new Horse(i));
    }
    return horse;

  }

  /**
   * 创建位置.
   * 
   * @return
   */
  private List<HorseRaceSeat> createSeats() {
    List<HorseRaceSeat> seats = new ArrayList<>(SEAT_NUM);
    for (int i = 0; i < SEAT_NUM; i++) {
      seats.add(new HorseRaceSeat(i, this));
    }

    return Collections.unmodifiableList(seats);

  }

  /**
   * 获取倍率.
   * 
   * 
   * @param areId .
   * @return
   */
  public int getAmapMult(int areId) {
    int mult = 1;
    for (AreBet areBet : areBetMap.values()) {
      if (areBet.getAreId() == areId) {
        mult = areBet.getMultiple();
        break;
      }
    }
    if (mult == 1) {
      System.err.println("Erroo -------------------------------------");
    }
    return mult;
  }

  /**
   * 获取开奖区域.
   * 
   * 
   * @param areId .
   * @return
   */
  public AreBet getArea(int areId) {
    AreBet area = null;
    for (AreBet areBet : areBetMap.values()) {
      if (areBet.getAreId() == areId) {
        area = areBet;
        break;
      }
    }
    return area;
  }

  /**
   * 获取开奖区域.
   * 
   * 
   * @param areA .
   * @return
   */
  public int getHorse(int areA) {
    int area = 0;
    for (Entry<Integer, AreBet> areBet : areBetMap.entrySet()) {
      if (areBet.getValue().getAreId() == areA) {
        area = areBet.getKey();
        break;
      }
    }
    return area;

  }

  /**
   * 创建下注区域.
   * 
   * 
   */
  public void createAreMap() {
    AreBet areBet1 = new AreBet(1, 6);
    AreBet areBet2 = new AreBet(1, 5);
    AreBet areBet3 = new AreBet(1, 4);
    AreBet areBet4 = new AreBet(1, 3);
    AreBet areBet5 = new AreBet(1, 2);
    AreBet areBet6 = new AreBet(2, 6);
    AreBet areBet7 = new AreBet(2, 5);
    AreBet areBet8 = new AreBet(2, 4);
    AreBet areBet9 = new AreBet(2, 3);
    AreBet areBet10 = new AreBet(3, 6);
    AreBet areBet11 = new AreBet(3, 5);
    AreBet areBet12 = new AreBet(3, 4);
    AreBet areBet13 = new AreBet(4, 6);
    AreBet areBet14 = new AreBet(4, 5);
    AreBet areBet15 = new AreBet(5, 6);
    this.areBetMap.put(1, areBet1);
    this.areBetMap.put(2, areBet2);
    this.areBetMap.put(3, areBet3);
    this.areBetMap.put(4, areBet4);
    this.areBetMap.put(5, areBet5);
    this.areBetMap.put(6, areBet6);
    this.areBetMap.put(7, areBet7);
    this.areBetMap.put(8, areBet8);
    this.areBetMap.put(9, areBet9);
    this.areBetMap.put(10, areBet10);
    this.areBetMap.put(11, areBet11);
    this.areBetMap.put(12, areBet12);
    this.areBetMap.put(13, areBet13);
    this.areBetMap.put(14, areBet14);
    this.areBetMap.put(15, areBet15);
  }

  /**
   * 给每匹马排名 . - 通过时间来定 .
   */
  public void horseRank() {
    AreBet areBet = getArea(this.horse);
    // AreBet areBet = aMap.get(this.horse);
    // System.err.println("房间ID:" + this.room().id + " 开出结果： " + this.horse);
    int time = firstAndSecendHorse(areBet);
    for (Horse horse : horses) {
      if (horse.getId() != areBet.getHorse1() && horse.getId() != areBet.getHorse2()) {
        horse.setSegment(RandCodeUtil.random(3, 15));
        horse.setTotalTime(RandCodeUtil.random(200, 1000) + time);
        horse.addPerTime();
      }
    }
  }

  /**
   * 决定第一第二名 .
   * 
   * 
   * @param areBet .
   * @return
   */
  public int firstAndSecendHorse(AreBet areBet) {
    int time = 0;
    int horseId = 0;
    for (Horse horse : horses) {
      if (horse.getId() == areBet.getHorse1()
          || horse.getId() == areBet.getHorse2() && horseId == 0) {
        horse.setSegment(RandCodeUtil.random(3, 15));
        time = RandCodeUtil.random(18000, 19000);
        horse.setTotalTime(time);
        horse.addPerTime();
        horseId = horse.getId();
      }
    }
    for (Horse horse : horses) {
      if ((horse.getId() == areBet.getHorse1() || horse.getId() == areBet.getHorse2())
          && horse.getId() != horseId) {
        horse.setSegment(RandCodeUtil.random(3, 15));
        time += RandCodeUtil.random(200, 1000);
        horse.setTotalTime(time);
        horse.addPerTime();
      }
    }
    return time;
  }

  /**
   * 机器人收益 .
   * 
   * @return
   */
  public long robotBill() {
    long bill = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      if (seat.isRobot()) {
        bill += seat.billChips;
      }
    }
    return bill;
  }

  /**
   * 真实玩家收益 .
   * 
   * @return
   */
  public long playerBill() {
    long bill = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      if (!seat.isRobot()) {
        bill += seat.billChips;
      }
    }
    return bill;
  }

  /**
   * 桌子玩家下注 .
   * 
   * @return
   */
  public Map<Integer, Long> tableBets() {
    Map<Integer, Long> tableBets = new HashMap<>();
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.bets.entrySet()) {
        int area = seatBetEtr.getKey();
        long areaBet = tableBets.getOrDefault(area, 0L);
        tableBets.put(area, areaBet + seatBetEtr.getValue());
      }
    }

    return tableBets;
  }

  /**
   * 玩家合计总下注 .
   * 
   * @return
   */
  public long playerTotalBets() {
    long playerTotalBets = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.bets.entrySet()) {
        if (!seat.isRobot()) {
          playerTotalBets += seatBetEtr.getValue();
        }
      }
    }

    return playerTotalBets;
  }

  /**
   * 玩家某个区域合计总下注 .
   * 
   * @param area .
   * @return
   */
  public Long playerareaBets(int area) {
    long playerareaBets = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.bets.entrySet()) {
        if (!seat.isRobot() && seatBetEtr.getKey() == area) {
          playerareaBets += seatBetEtr.getValue();
        }
      }
    }

    return playerareaBets;
  }

  /**
   * 机器人合计总下注 .
   * 
   * @return
   */
  public long robotTotalBets() {
    long robotTotalBets = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.bets.entrySet()) {
        if (seat.isRobot()) {
          robotTotalBets += seatBetEtr.getValue();
        }
      }
    }

    return robotTotalBets;
  }

  /**
   * 机器人某个区域合计总下注 .
   * 
   * @param area .
   * @return
   */
  public Long robotareaBets(int area) {
    long robotareaBets = 0;
    for (HorseRaceSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.bets.entrySet()) {
        if (seat.isRobot() && seatBetEtr.getKey() == area) {
          robotareaBets += seatBetEtr.getValue();
        }
      }
    }

    return robotareaBets;
  }

  /**
   * 桌子区域押注 .
   * 
   * @param area .
   * @return
   */
  public long bet(int area) {
    long areaBet = 0;
    for (HorseRaceSeat seat : seats) {
      areaBet += seat.bets.getOrDefault(area, 0L);
    }

    return areaBet;
  }

  /**
   * 重置桌子 .
   */
  public void reset() {
    this.earn = 0;
    this.totalChips = 0;
  }

  /**
   * 闲家合计筹码 .
   * 
   * @return
   */
  public long playesChips() {
    long playesChips = 0;
    for (HorseRaceSeat s : seats) {
      if (!s.dealer && s.getPlayerId() > 0) {
        playesChips += s.getTotalChips();
      }
    }

    return playesChips;
  }

  /**
   * 获取seat .
   * 
   * @param order .
   * @return
   */
  public HorseRaceSeat getSeat(int order) {

    return seats.get(order);
  }

  @SuppressWarnings("unchecked")
  @Override
  public HorseRaceRoom room() {
    return room;
  }

  @Override
  public List<HorseRaceSeat> seats() {

    return seats;
  }

}
